﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MWS.Processing.Processors;
using ThrottledProcessing.SampleApplication.Domain;
using ThrottledProcessing.SampleApplication.Interfaces;
using ThrottledProcessing.SampleApplication.Messages;
using ThrottledProcessing.SampleApplication.Services;

namespace ThrottledProcessing.SampleApplication.Processors
{
    public class DocumentIndexingProcessor : OperationProcessor<SearchRequest, SearchResponse>
    {
        private readonly ILoggingService loggingService;
        private readonly IDocumentService documentService;
        private readonly IList<string> keywordsToIndex;

        public DocumentIndexingProcessor() : this(new ConsoleLoggingService())
        {
        }

        public DocumentIndexingProcessor(ILoggingService loggingService)
            : this(
                new SearchService(loggingService), new DocumentService(loggingService),
                new List<string> {"Microsoft", "Google", "Oracle"})
        {
            this.loggingService = loggingService;
        }

        public DocumentIndexingProcessor(ISearchService searchService, IDocumentService documentService,
                                         IList<string> keywordsToIndex) : base(searchService.Search)
        {
            this.documentService = documentService;
            this.keywordsToIndex = keywordsToIndex;
            ProcessComplete += OnProcessComplete;
            Error += OnError;
        }

        private void OnError(object sender, ErrorEventArgs args)
        {
            loggingService.Error(args.Exception.Message);
        }

        public override void OnProcessComplete(object sender, ResponseEventArgs args)
        {
            loggingService.Debug("Processing results of search for keyword: " + args.Request.Query.Keyword);
            Parallel.ForEach(
                args.Response.Items,
                new ParallelOptions {MaxDegreeOfParallelism = ProcessRequestsMaxParallel},
                document => documentService.StoreDocument(document));
        }


        public override IList<SearchRequest> GetRequests(int maxRequests)
        {
            loggingService.Debug("Getting search requests.");
            return keywordsToIndex.Select(keyword => new SearchRequest
                                                         {
                                                             Query = new Query
                                                                         {
                                                                             Keyword = keyword,
                                                                             Page = 1,
                                                                             ResultsPerPage = 5
                                                                         }
                                                         }).Take(maxRequests).ToList();
        }
    }
}